Flutter で QR コードスキャンを実装できる mobile_scanner を Web アプリで試してみた
こんにちは、CX事業本部 Delivery部の若槻です。
Flutter アプリケーションで QR コードスキャナーを実装したい場合には、下記のようにパッケージの選択肢がいくつかあります。
パッケージ | LIKES | PUB POINTS | POPULARITY | Last Published |
---|---|---|---|---|
mobile_scanner | 1139 | 130 | 99% | 38 days ago |
qr_code_scanner | 1798 | 120 | 99% | 13 months ago |
zxing2 | 42 | 140 | 95% | 7 months agos |
最も枯れているのは qr_code_scanner ですが、メンテナンスモードとなりしばらく更新されていません。よって現在最も有力なのは下記の mobile_scanner のようです。mobile_scanner は iOS、Android に加えて Web および macOS にも対応しています。
今回は mobile_scanner を使った Flutter アプリでの QR コードスキャンの実装を Web で試してみました。
試してみた
環境
$ flutter --version Flutter 3.7.7 • channel stable • https://github.com/flutter/flutter.git Framework • revision 2ad6cd72c0 (6 months ago) • 2023-03-08 09:41:59 -0800 Engine • revision 1837b5be5f Tools • Dart 2.19.4 • DevTools 2.20.1
プロジェクト作成
flutter create my_app code my_app
パッケージ導入
flutter pub add mobile_scanner
導入されました。
$ git diff pubspec.yaml diff --git a/pubspec.yaml b/pubspec.yaml index 4dfe6bc..ac5348d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + mobile_scanner: ^3.4.1 dev_dependencies: flutter_test:
index.html の修正
index.html
に下記を追加して、ZXing on Web を読み込むようにします。
<script src="https://unpkg.com/@zxing/library@0.19.1" type="application/javascript"></script>
実装
Usage を参考に実装してみます。
import 'package:flutter/material.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; void main() => runApp(const MaterialApp(home: MyHome())); class MyHome extends StatelessWidget { const MyHome({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Mobile Scanner')), body: MobileScanner( // fit: BoxFit.contain, onDetect: (capture) { final List<Barcode> barcodes = capture.barcodes; // final Uint8List? image = capture.image; for (final barcode in barcodes) { debugPrint('Barcode found! ${barcode.rawValue}'); } }, ), ); } }
MobileScanner()
を使用すると端末のカメラが起動します。onDetect
を使用することにより、QR コードが読み取れた際の処理を記述できます。capture.barcodes
で読み取ったバーコードのリストを取得できます。capture.image
で読み取った画像バイナリを取得できます。
動作確認
アプリケーションを起動します。
flutter run -d chrome
起動時にカメラのパーミッションを求められるので許可します。
AppBar 以外の部分がカメラ映像となります。QR コードをカメラにかざすと自動で読み取られます。
次のようにカメラ映像内に QR コードが映っている間は継続して読み取られます。実際の実装では、読み取りが完了したら別の画面に遷移するなどの処理を行うことになると思います。
$ flutter run -d chrome Launching lib/main.dart on Chrome in debug mode... Waiting for connection from debug service on Chrome... 10.3s This app is linked to the debug service: ws://127.0.0.1:61158/fuksFUIMVMQ=/ws Debug service listening on ws://127.0.0.1:61158/fuksFUIMVMQ=/ws 💪 Running with sound null safety 💪 🔥 To hot restart changes while running, press "r" or "R". For a more detailed help message, press "h". To quit, press "q". An Observatory debugger and profiler on Chrome is available at: http://127.0.0.1:61158/fuksFUIMVMQ= The Flutter DevTools debugger and profiler on Chrome is available at: http://127.0.0.1:9103?uri=http://127.0.0.1:61158/fuksFUIMVMQ= Barcode found! https://ja.wikipedia.org/ Barcode found! https://ja.wikipedia.org/ Barcode found! https://ja.wikipedia.org/ Barcode found! https://ja.wikipedia.org/ Barcode found! https://ja.wikipedia.org/ Barcode found! https://ja.wikipedia.org/
遭遇したエラー
前述の実装のアプリケーション実行時に下記のエラーが発生しました。
══╡ EXCEPTION CAUGHT BY SERVICES LIBRARY ╞══════════════════════════════════════════════════════════ The following MissingPluginException was thrown while activating platform stream on channel dev.steenbakker.mobile_scanner/scanner/event: MissingPluginException(No implementation found for method listen on channel dev.steenbakker.mobile_scanner/scanner/event) When the exception was thrown, this was the stack: dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49 throw_ packages/flutter/src/services/platform_channel.dart 313:7 _invokeMethod dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50 <fn> dart-sdk/lib/async/zone.dart 1660:54 runUnary dart-sdk/lib/async/future_impl.dart 147:18 handleValue dart-sdk/lib/async/future_impl.dart 767:44 handleValueCallback dart-sdk/lib/async/future_impl.dart 796:13 _propagateToListeners dart-sdk/lib/async/future_impl.dart 567:5 [_completeWithValue] dart-sdk/lib/async/future_impl.dart 640:7 callback dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15 <fn> ════════════════════════════════════════════════════════════════════════════════════════════════════ Error: Expected a value of type 'MobileScannerException', but got one of type 'MissingPluginException' dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49 throw_ dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 99:3 castError dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 485:10 cast dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart 638:14 as_C packages/mobile_scanner/src/mobile_scanner.dart 142:35 <fn> packages/flutter/src/widgets/framework.dart 1133:30 setState packages/mobile_scanner/src/mobile_scanner.dart 141:9 <fn> dart-sdk/lib/async/zone.dart 1660:54 runUnary dart-sdk/lib/async/future_impl.dart 165:22 handleError dart-sdk/lib/async/future_impl.dart 779:46 handleError dart-sdk/lib/async/future_impl.dart 800:13 _propagateToListeners dart-sdk/lib/async/future_impl.dart 567:5 [_completeWithValue] dart-sdk/lib/async/future_impl.dart 640:7 callback dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15 <fn>
原因としては、Flutter 本体を読み込む前に ZXing on Web を読み込む必要があったためでした。追記位置に注意してください。
+ <script src="https://unpkg.com/@zxing/library@0.19.1" type="application/javascript"></script> <script src="flutter.js" defer></script> - <script src="https://unpkg.com/@zxing/library@0.19.1" type="application/javascript"></script>
おわりに
Flutter で QR コードスキャンを実装できる mobile_scanner を Web アプリで試してみました。
mobile_scanner はスコアが高いとは言いつつネット上にあまり情報がないのが心配だったのですが、使ってみると思った以上に簡単に QR コードスキャンを実装することができました。
次回は iOS アプリでも試してみたいと思います。
参考
以上